package com.jwsoft.manager.core.integration.impl;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.lang.Snowflake;
import cn.hutool.core.util.IdUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.bifang.assistant.common.vo.BaseVO;
import com.bifang.engine.assistant.core.annotation.ApiService;
import com.bifang.engine.assistant.core.annotation.OpApi;
import com.bifang.engine.assistant.core.annotation.SaveOplog;
import com.bifang.engine.assistant.core.enums.AuTypeEnum;
import com.bifang.engine.assistant.core.enums.FuncTypeEnum;
import com.bifang.engine.assistant.core.utils.SessionUtil;
import com.bifang.engine.cache.redis.RedisHelper;
import com.bifang.engine.data.core.util.PagerUtil;
import com.bifang.engine.protect.core.annotation.NoSignCrypto;
import com.bifang.module.base.common.vo.common.CommonVO;
import com.bifang.module.base.core.integration.CommonIntegration;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.jwsoft.manager.common.constant.EduCache;
import com.jwsoft.manager.common.enums.AreaEnum;
import com.jwsoft.manager.common.enums.EduAddressTreeHandleStatusTypeEnum;
import com.jwsoft.manager.common.enums.HandleStatusEnum;
import com.jwsoft.manager.common.enums.SchoolCategoryEnum;
import com.jwsoft.manager.common.vo.addressParse.AddressInfo;
import com.jwsoft.manager.common.vo.eduAddress.EduAddressQueryVO;
import com.jwsoft.manager.common.vo.eduAddress.EduAddressVO;
import com.jwsoft.manager.common.vo.eduAddressTree.EduAddressTreeVO;
import com.jwsoft.manager.common.vo.eduSchool.EduSchoolVO;
import com.jwsoft.manager.core.dao.model.*;
import com.jwsoft.manager.core.dao.service.*;
import com.jwsoft.manager.core.integration.addressParse.SmartParse;
import com.jwsoft.manager.core.integration.eduAddressTree.EduAddressTreeIntegration;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.math3.stat.correlation.Covariance;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Lazy;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.support.TransactionCallbackWithoutResult;
import org.springframework.transaction.support.TransactionTemplate;
import org.springframework.util.CollectionUtils;
import cn.hutool.core.convert.Convert;

import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.stream.Collectors;

import com.bifang.engine.assistant.core.exception.AppException;
import org.springframework.util.ObjectUtils;
import org.springframework.transaction.annotation.Transactional;
import com.bifang.engine.assistant.core.enums.BoolEnum;
import com.jwsoft.manager.common.vo.eduAddressTreeInitial.EduAddressTreeInitialVO;
import com.jwsoft.manager.common.vo.eduAddressTreeInitial.EduAddressTreeInitialKeyVO;
import com.jwsoft.manager.common.vo.eduAddressTreeInitial.EduAddressTreeInitialQueryVO;
import com.jwsoft.manager.core.integration.EduAddressTreeInitialIntegration;

/**
 * 初始地址树表业务实现类
 *
 * @author zhiyuan
 * @since 2024-01-09
 */
@ApiService(funcCode = "addressTreeInitial", title = "初始地址树表")
@Slf4j
public class EduAddressTreeInitialIntegrationImpl implements EduAddressTreeInitialIntegration {

    @Autowired
    public EduAddressTreeInitialService eduAddressTreeInitialService;

    @Autowired
    private EduAddressService eduAddressService;

    @Value("${system.config.snowflake.workerId:1}")
    private Long workerId;

    @Autowired
    private EduAddressTreeOriginalService originalService;

    @Autowired
    private TransactionTemplate transactionTemplate;

    @Autowired
    private EduAddressSchoolService addressSchoolService;

    @Autowired
    private EduAddressTreeService addressTreeService;

    @Autowired
    private CommonIntegration commonIntegration;

    @Autowired
    private RedisHelper redisHelper;

    //最大的处理数量
    private static final Integer HANDLE_MAX_COUNT = 100000;

    //地址解析最大分页数量
    private static final Integer MAX_LIMIT = 1000;


    @Autowired
    private SmartParse smartParse;

    @Autowired
    @Lazy
    private EduAddressTreeIntegration initialIntegration;
    @Override
    @OpApi(funcCode = "addressTreeInitial0001", title = "初始地址树表分页查询", funcType = FuncTypeEnum.query)
    public PageInfo<EduAddressTreeInitialVO> getList(EduAddressTreeInitialQueryVO vo) {
        // 开启分页
        if (vo.getPageNum() == null || vo.getPageSize() == null) {
            //如果不传入分页参数，默认最大取1000条
            vo.setPageNum(1);
            vo.setPageSize(1000);
        }
        PageHelper.startPage(vo.getPageNum(),vo.getPageSize());
        List<EduAddressTreeInitial> list = eduAddressTreeInitialService.list();
        if (CollectionUtils.isEmpty(list)) {
            // 判断是否为空，为空则返回空参数
            return PagerUtil.createEmptyPagerInfo(vo.getPageNum(), vo.getPageSize());
        }
        // 不为空则获取分页结果
        PageInfo<EduAddressTreeInitial> pageInfo = new PageInfo<>(list);
        // 返回参数需要通过common层的vo实体类，用该方法可以批量转换
        List<EduAddressTreeInitialVO> resultList = Convert.toList(EduAddressTreeInitialVO.class, pageInfo.getList());
        // 转义数据字典值
        // dictHelper.valueToName(resultList, Arrays.asList(DemoDictEnum.values()));
        return PagerUtil.parsePagerVo(resultList, pageInfo);
    }

    @Override
    @OpApi(funcCode = "addressTreeInitial0002", title = "初始地址树表根据主键查询详情", funcType = FuncTypeEnum.query)
    public EduAddressTreeInitialVO getById(EduAddressTreeInitialKeyVO vo) {
        EduAddressTreeInitial entity = eduAddressTreeInitialService.getById(vo.getAddressId());
        if (ObjectUtils.isEmpty(entity)) {
            throw new AppException("查询不到详细信息!");
        }
        EduAddressTreeInitialVO result = Convert.convert(EduAddressTreeInitialVO.class, entity);
        return result;
    }
    /** 保存前统一校验*/
    @Override
    @OpApi(funcCode = "addressTreeInitial0003", title = "初始地址树表保存前校验", funcType = FuncTypeEnum.other ,checkPrivilege = BoolEnum.FALSE)
    public void checkSave(EduAddressTreeInitialVO vo) {
        //主键为空为新增校验

        //主键不为空为修改校验
    }

    @Override
    @OpApi(funcCode = "addressTreeInitial0004", title = "初始地址树表新增", funcType = FuncTypeEnum.insert)
    @Transactional
    public EduAddressTreeInitialVO add(EduAddressTreeInitialVO vo) {
        //保存前校验
        checkSave(vo);
        //保存数据
        EduAddressTreeInitial entity = Convert.convert(EduAddressTreeInitial.class, vo);
        eduAddressTreeInitialService.save(entity);
        //将主键设置回vo使操作日志可以取到
        vo.setAddressId(entity.getAddressId());
        return vo;
    }

    @Override
    @OpApi(funcCode = "addressTreeInitial0005", title = "初始地址树表修改", funcType = FuncTypeEnum.update)
    @Transactional
    public EduAddressTreeInitialVO edit(EduAddressTreeInitialVO vo) {
        if (ObjectUtils.isEmpty(vo.getAddressId())) {
            throw new AppException("传入需要修改的主键不能为空!");
        }
        EduAddressTreeInitial oldEntity = eduAddressTreeInitialService.getById(vo.getAddressId());
        if (ObjectUtils.isEmpty(oldEntity)) {
            throw new AppException("查询不到需要修改的信息!");
        }
        //保存前校验
        checkSave(vo);
        //保存数据
        EduAddressTreeInitial entity = Convert.convert(EduAddressTreeInitial.class, vo);
        eduAddressTreeInitialService.updateById(entity);
        return vo;
    }

    @Override
    @OpApi(funcCode = "addressTreeInitial0006", title = "初始地址树表根据主键删除", funcType = FuncTypeEnum.delete)
    @Transactional
    public void del(EduAddressTreeInitialKeyVO vo) {
        if (ObjectUtils.isEmpty(vo.getAddressId())) {
            throw new AppException("传入需要删除的数据主键不能为空!");
        }
        EduAddressTreeInitial entity = eduAddressTreeInitialService.getById(vo.getAddressId());
        if (ObjectUtils.isEmpty(entity)) {
            throw new AppException("未找到需要删除的信息!");
        }
        eduAddressTreeInitialService.removeById(vo.getAddressId());
    }

    @Override
    @OpApi(funcCode = "addressTreeInitial0007", title = "初始地址树生成并初始化学区", funcType = FuncTypeEnum.other)
    @NoSignCrypto
    public void addressTreeCreate(EduAddressTreeInitialQueryVO vo) {
        if (ObjectUtils.isEmpty(vo.getInitialSchoolFlag())){
            vo.setInitialSchoolFlag(true);
        }
        //处理累加器
        AtomicInteger handleCount = new AtomicInteger(0);
        int count = 0;
        String redisKey = EduCache.EDU_ADDRESS_TREE_INIT;
        boolean lock = false;
        lock = redisHelper.hasKey(redisKey);
        if (lock) {
            throw new AppException("地址树正在进行初始化，请稍后再试");
        }else{
            redisHelper.set(redisKey, true, 43200);
            Boolean isLastPage = false;
            while (!isLastPage){
                EduAddressQueryVO queryVo = Convert.convert(EduAddressQueryVO.class, vo);
                queryVo.setAddressId(vo.getParseAddressId());
                if (StringUtils.isBlank(queryVo.getHandleStatus())){
                    //如果未传入解析的状态，默认解析未处理的地址
                    queryVo.setHandleStatus(EduAddressTreeHandleStatusTypeEnum.UNTREATED.getType());
                }
                queryVo.setLimitCount(MAX_LIMIT);
                queryVo.setFictitious(BoolEnum.FALSE.getType());
                List<EduAddress> list = eduAddressService.getList(queryVo);
                if (!CollectionUtils.isEmpty(list)){
                    for (EduAddress eduAddress : list) {
                        try {
                            Thread.sleep(10); // 睡眠10毫秒
                        } catch (InterruptedException e) {
                            Thread.currentThread().interrupt(); // 重新设置中断状态
                        }
                        //不管怎么样，都要进行累加
                        count = handleCount.incrementAndGet();
                        this.performParseAddress(eduAddress,vo.getInitialSchoolFlag());
                    }
                    //处理完成一个limit之后， 判断是否处理到最后一页数据
                    if ( MAX_LIMIT > list.size()) {
                        isLastPage = true;
                    }
                    //最大处理数量 超过就直接退出
                    if (count >= HANDLE_MAX_COUNT){
                        isLastPage = true;
                    }
                }else{
                    isLastPage = true;
                }
            }
            redisHelper.del(redisKey);
        }
    }

    @Override
    @OpApi(funcCode = "addressTreeInitial0008", title = "解析地址为树节点，不初始化学区", funcType = FuncTypeEnum.other)
    @NoSignCrypto
    public void parseAddressTree(EduAddressTreeInitialQueryVO vo) {
        vo.setInitialSchoolFlag(false);
        addressTreeCreate(vo);
    }

    @Override
    public void parseAddressTree(EduAddress eduAddress, Boolean initialSchoolFlag){
        try {
            //解析地址
            parseAddress(eduAddress,initialSchoolFlag);
        } catch (Exception e) {
            String msg=e.getMessage();
            if(StringUtils.isNotBlank(msg)&&msg.length()>300){
                msg=msg.substring(0,200);
            }
            UpdateWrapper<EduAddress> updateWrapper = new UpdateWrapper<>();
            updateWrapper.lambda()
                    .eq(EduAddress::getAddressId, eduAddress.getAddressId())
                    .set(EduAddress::getHandleStatus,EduAddressTreeHandleStatusTypeEnum.HANDLEERROR.getType())
                    .set(EduAddress::getHandleMessage,msg)
                    .set(EduAddress::getHandleTime, eduAddress.getHandleTime())
                    .set(EduAddress::getUpdateTime,new Date());
            eduAddressService.update(updateWrapper);
            log.error("地址解析失败:{}", e.getMessage());
        }
    }

    /**
     * 执行解析地址的方法，采用编程式事务
     * @param eduAddress
     * @param initialSchoolFlag
     */
    private void performParseAddress(EduAddress eduAddress, Boolean initialSchoolFlag) {
        transactionTemplate.execute(new TransactionCallbackWithoutResult() {
            @Override
            protected void doInTransactionWithoutResult(TransactionStatus status) {
                try {
                    //解析地址
                    parseAddress(eduAddress,initialSchoolFlag);
                } catch (Exception e) {
                    status.setRollbackOnly();
                    String msg=e.getMessage();
                    if(StringUtils.isNotBlank(msg)&&msg.length()>300){
                        msg=msg.substring(0,200);
                    }
                    UpdateWrapper<EduAddress> updateWrapper = new UpdateWrapper<>();
                    updateWrapper.lambda()
                            .eq(EduAddress::getAddressId, eduAddress.getAddressId())
                            .set(EduAddress::getHandleStatus,EduAddressTreeHandleStatusTypeEnum.HANDLEERROR.getType())
                            .set(EduAddress::getHandleMessage,msg)
                            .set(EduAddress::getHandleTime, eduAddress.getHandleTime())
                            .set(EduAddress::getUpdateTime,new Date());
                    eduAddressService.update(updateWrapper);
                }
            }
        });
    }

    /**
     * 地址解析
     *
     * @param eduAddress
     * @param initialSchoolFlag
     */
    public void parseAddress(EduAddress eduAddress, Boolean initialSchoolFlag) {
        AddressInfo addressInfo = smartParse.parseAddressInfo(eduAddress.getAddressName());
        if (ObjectUtils.isEmpty(addressInfo)) {
            UpdateWrapper<EduAddress> updateWrapper = new UpdateWrapper<>();
            updateWrapper.lambda()
                    .eq(EduAddress::getAddressId, eduAddress.getAddressId())
                    .set(EduAddress::getHandleStatus,EduAddressTreeHandleStatusTypeEnum.HANDLEERROR.getType())
                    .set(EduAddress::getHandleMessage,"处理失败，地址解析有误")
                    .set(EduAddress::getHandleTime, eduAddress.getHandleTime())
                    .set(EduAddress::getUpdateTime,new Date());
            eduAddressService.update(updateWrapper);
            return;
        }
        //保存解析的树节点信息
        saveTreeNodeByAddressInfo(addressInfo,eduAddress,initialSchoolFlag);
    }

    /**
     * 地址解析完成之后，调用该方法进行保存
     * @param addressInfo 地址解析信息
     * @param eduAddress 地址信息
     * @param initialSchoolFlag 是否初始化学校
     *                          true：初始化地址节点和学区，保存到edu_address_tree_school中
     *                          false:不做操作
     */
    @Override
    public void saveTreeNodeByAddressInfo(AddressInfo addressInfo, EduAddress eduAddress, Boolean initialSchoolFlag) {
        if (ObjectUtils.isEmpty(initialSchoolFlag)){
            //默认不初始化学区
            initialSchoolFlag = false;
        }
        //如果地址解析正确
        UpdateWrapper<EduAddress> updateWrapper=new UpdateWrapper<>();
        updateWrapper.lambda().eq(EduAddress::getAddressId,eduAddress.getAddressId())
                .set(EduAddress::getHandleTime,new Date());
        if (addressInfo.getErrorStatus() == 0){
            updateWrapper.lambda().set(EduAddress::getHandleStatus,EduAddressTreeHandleStatusTypeEnum.HANDLESUCCESS.getType())
                    .set(EduAddress::getHandleMessage,EduAddressTreeHandleStatusTypeEnum.HANDLESUCCESS.getName())
                    .set(EduAddress::getAreaCode,addressInfo.getDistrictCode())
                    .set(EduAddress::getCityCode,addressInfo.getCityCode())
                    .set(EduAddress::getStreetCode,addressInfo.getTownCode());
            //保存到初始化地址树表中
            eduAddress = saveToAddressTreeInitial(addressInfo,eduAddress,initialSchoolFlag);
            updateWrapper.lambda()
                    .set(EduAddress::getAddressTreeId,eduAddress.getAddressTreeId())
                    .set(StringUtils.isNotBlank(eduAddress.getParentPath()),EduAddress::getParentPath,eduAddress.getParentPath())
                    .set(EduAddress::getMatchingMessage, eduAddress.getMatchingMessage())
                    .set(EduAddress::getMatchingStatus,eduAddress.getMatchingStatus())
                    .set(EduAddress::getMatchingTime,new Date());
        }else if (addressInfo.getErrorStatus() == 1){
            //处理错误地址
            eduAddress = handleAddressError(eduAddress, addressInfo,initialSchoolFlag);
            updateWrapper.lambda().set(EduAddress::getHandleStatus,eduAddress.getHandleStatus())
                    .set(EduAddress::getHandleMessage,eduAddress.getHandleMessage());
            if(BoolEnum.TRUE.getType().equalsIgnoreCase(eduAddress.getHandleStatus())){
                updateWrapper.lambda().set(EduAddress::getAreaCode,addressInfo.getDistrictCode())
                        .set(EduAddress::getCityCode,addressInfo.getCityCode())
                        .set(EduAddress::getStreetCode,addressInfo.getTownCode())
                        .set(StringUtils.isNotBlank(eduAddress.getParentPath()),EduAddress::getParentPath,eduAddress.getParentPath())
                        .set(EduAddress::getAddressTreeId,eduAddress.getAddressTreeId())
                        .set(EduAddress::getMatchingMessage, eduAddress.getMatchingMessage())
                        .set(EduAddress::getMatchingStatus,eduAddress.getMatchingStatus())
                        .set(EduAddress::getMatchingTime,new Date());
            }

        }else if (addressInfo.getErrorStatus() == 9){
            // 市外地址，不予处理
            updateWrapper.lambda().set(EduAddress::getHandleStatus,EduAddressTreeHandleStatusTypeEnum.NOHANDLE.getType())
                    .set(EduAddress::getHandleMessage,addressInfo.getErrorDetail());
            eduAddress.setHandleStatus(EduAddressTreeHandleStatusTypeEnum.NOHANDLE.getType());
            eduAddress.setHandleMessage(addressInfo.getErrorDetail());
        }
        //处理每条eduAddress状态
        eduAddressService.update(updateWrapper);
    }

    @Override
    public void clearCache(BaseVO vo) {
        String redisKey = EduCache.EDU_ADDRESS_TREE_INIT;
        redisHelper.del(redisKey);
        redisHelper.del(EduCache.EDU_ADDRESS_TREE_MATCH_AREA);
    }

    /**
     * 处理地址解析出错的地址
     *
     * @param eduAddress
     * @param addressInfo
     * @param initialSchoolFlag
     */
    private EduAddress handleAddressError(EduAddress eduAddress, AddressInfo addressInfo, Boolean initialSchoolFlag) {
        //判断该地址是否有地址标记
        Boolean signFlag = checkCodeSign(eduAddress,addressInfo);
        if (signFlag){
            eduAddress.setHandleStatus(EduAddressTreeHandleStatusTypeEnum.HANDLESUCCESS.getType());
            eduAddress.setHandleMessage((EduAddressTreeHandleStatusTypeEnum.HANDLESUCCESS.getName()));
            //校验节点是否存在数据库中
            addressInfo.setParseNodes(smartParse.checkAddressNodes(addressInfo.getParseNodes()));
            //设置所属标志行政区划代码
            addressInfo.setCityCode(eduAddress.getCityCode());
            addressInfo.setDistrictCode(eduAddress.getAreaCode());
            addressInfo.setTownCode(eduAddress.getStreetCode());
            return saveToAddressTreeInitial(addressInfo, eduAddress,initialSchoolFlag);
        }
        CommonVO addressParseCheck = new CommonVO();
        addressParseCheck.setParamKey("address_vague_parse_check");
        String checkValue = commonIntegration.getValueByKey(addressParseCheck);
        // 没有值，默认关闭地址模糊解析校验
        if (StringUtils.isBlank(checkValue)){
            //没有值，默认关闭地址模糊解析校验
            checkValue = BoolEnum.FALSE.getType();
        }
        if (BoolEnum.TRUE.getType().equals(checkValue)) {
            // 第一步解析到未能识别区县的地址，根据已插入的初始化节点，进行继续校验
            boolean isValid = checkDistrictWithError(addressInfo);
            eduAddress.setHandleStatus(isValid
                    ? EduAddressTreeHandleStatusTypeEnum.HANDLESUCCESS.getType()
                    : EduAddressTreeHandleStatusTypeEnum.HANDLEERROR.getType());

            eduAddress.setHandleMessage(isValid ?
                    EduAddressTreeHandleStatusTypeEnum.HANDLESUCCESS.getName() :
                    addressInfo.getErrorDetail());
            if (isValid) {
                //校验节点是否存在数据库中
                addressInfo.setParseNodes(smartParse.checkAddressNodes(addressInfo.getParseNodes()));
                eduAddress =  saveToAddressTreeInitial(addressInfo, eduAddress,initialSchoolFlag);
            }
        } else {
            eduAddress.setHandleMessage(addressInfo.getErrorDetail());
            eduAddress.setHandleStatus(EduAddressTreeHandleStatusTypeEnum.HANDLEERROR.getType());
            eduAddress.setAddressTreeId(null);
        }
        return eduAddress;
    }

    /**
     * 校验是否有地址标记
     * @param eduAddress
     * @param addressInfo
     * @return
     */
    private Boolean checkCodeSign(EduAddress eduAddress, AddressInfo addressInfo) {
        if (addressInfo == null){
            return  false;
        }
        if(CollectionUtils.isEmpty(addressInfo.getParseNodes())){
            return false;
        }
        //将解析好的地址进行分组，按照节点类型areaType
        Map<String, List<EduAddressTreeInitialVO>> areaTypeMap = addressInfo.getParseNodes()
                .stream().collect(Collectors.groupingBy(EduAddressTreeInitialVO::getAreaType));
        //如果地址未标记 直接结束
        if (StringUtils.isBlank(eduAddress.getAreaCode())){
            return false;
        }
        //检查是否有区县标记
        QueryWrapper<EduAddressTreeOriginal> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(EduAddressTreeOriginal::getAreaCode, eduAddress.getAreaCode());
        EduAddressTreeOriginal original = originalService.getOne(queryWrapper, false);
        if (ObjectUtils.isEmpty(original)){
            //没用区县标记，返回
            return false;
        }
        EduAddressTreeInitialVO districtNode = new EduAddressTreeInitialVO();
        EduAddressTreeInitialVO townNode = null;
        districtNode.setAddressId(original.getAddressId());
        districtNode.setAreaCode(original.getAreaCode());
        districtNode.setAreaType(AreaEnum.district.getType());
        districtNode.setAreaName(original.getAreaName());
        districtNode.setParentId(Long.valueOf(original.getParentId()));
        List<EduAddressTreeInitialVO> nodeList = new ArrayList<>();

        //得到district上级节点数据
        List<EduAddressTreeOriginal> originalLink = originalService.getAllLinkByOriginalId(districtNode.getAddressId());
        List<EduAddressTreeInitialVO> districtNodeLink = Convert.toList(EduAddressTreeInitialVO.class, originalLink);
        //改变父级节点
        if (areaTypeMap.containsKey(AreaEnum.province.getType())){
            nodeList.add(areaTypeMap.get(AreaEnum.province.getType()).get(0));
        }
        if(areaTypeMap.containsKey(AreaEnum.city.getType())) {
            nodeList.add(areaTypeMap.get(AreaEnum.city.getType()).get(0));
        }
        nodeList.addAll(districtNodeLink);
        //改变子级节点
        if(areaTypeMap.containsKey(AreaEnum.town.getType())) {
            nodeList.add(areaTypeMap.get(AreaEnum.town.getType()).get(0));
        }else{
            QueryWrapper<EduAddressTreeOriginal> townQuery = new QueryWrapper<>();
            townQuery.lambda().eq(EduAddressTreeOriginal::getAreaCode, eduAddress.getStreetCode());
            EduAddressTreeOriginal townOriginal = originalService.getOne(townQuery, false);
            if (!ObjectUtils.isEmpty(townOriginal)){
                townNode = new EduAddressTreeInitialVO();
                townNode.setAddressId(townOriginal.getAddressId());
                townNode.setAreaCode(townOriginal.getAreaCode());
                townNode.setAreaType(AreaEnum.town.getType());
                townNode.setAreaName(townOriginal.getAreaName());
                townNode.setParentId(Long.valueOf(townOriginal.getParentId()));
                nodeList.add(townNode);
            }
        }

        //原始节点列表剔除省市县街道 保留以下节点顺序排列  nodeList已经收集了省市县街道
        List<EduAddressTreeInitialVO> parseNodes = addressInfo.getParseNodes();
        //要提出的集合
        List<EduAddressTreeInitialVO> nodesToRemove = new ArrayList<>();

        for (EduAddressTreeInitialVO parseNode : parseNodes) {
            if (parseNode.getAreaType().equals(AreaEnum.province.getType())
                    || parseNode.getAreaType().equals(AreaEnum.city.getType())
                    || parseNode.getAreaType().equals(AreaEnum.district.getType())
                    || parseNode.getAreaType().equals(AreaEnum.town.getType())){
                nodesToRemove.add(parseNode);
            }
        }
        //得到剩余后的list
        parseNodes.removeAll(nodesToRemove);
        List<EduAddressTreeInitialVO> residueList = Convert.toList(EduAddressTreeInitialVO.class, parseNodes);
        nodeList.addAll(residueList);
        if (!ObjectUtils.isEmpty(townNode)){
            //返回district 所在索引位置 修改区县下一个节点的父id
            int townIndex = nodeList.indexOf(townNode);
            nodeList.get(townIndex +1).setParentId(townNode.getAddressId());
        }else{
            //返回district 所在索引位置 修改区县下一个节点的父id
            int districtIndex = nodeList.indexOf(districtNode);
            nodeList.get(districtIndex +1).setParentId(districtNode.getAddressId());
        }
        //替换解析节点列表
        addressInfo.setParseNodes(nodeList);
        return true;
    }

    /**
     * 初步解析出错的地址，根据已插入的初始化节点，进行继续校验
     * @param addressInfo
     */
    private Boolean checkDistrictWithError(AddressInfo addressInfo) {
        boolean isValid = false;
        ArrayList<EduAddressTreeInitialVO> removeList = new ArrayList<>();
        List<EduAddressTreeInitialVO> parseNodes = addressInfo.getParseNodes();
        for (int i = 0; i < parseNodes.size(); i++) {
            EduAddressTreeInitialVO node = parseNodes.get(i);
            //识别路节点
            if (node.getAreaType().equals(AreaEnum.road.getType())){
                QueryWrapper<EduAddressTreeInitial> queryWrapper = new QueryWrapper<>();
                queryWrapper.lambda()
                        .select(EduAddressTreeInitial::getAddressId,
                                EduAddressTreeInitial::getAreaName,
                                EduAddressTreeInitial::getAreaType,
                                EduAddressTreeInitial::getParentId)
                        .eq(EduAddressTreeInitial::getAreaType,node.getAreaType())
                        .eq(EduAddressTreeInitial::getAreaName,node.getAreaName());
                //从解析表中查找是否有同名同类型的节点
                List<EduAddressTreeInitial> list = eduAddressTreeInitialService.list(queryWrapper);
                if (CollectionUtils.isEmpty(list)){
                    return false;
                }
                //判断下一个节点是否为路编号
                if (i + 1 < parseNodes.size()){
                    EduAddressTreeInitialVO nextNode = parseNodes.get(i + 1);
                    if (nextNode.getAreaType().equals(AreaEnum.roadNumber.getType())){
                        outerRoadLoop:
                        for (EduAddressTreeInitial initial : list) {
                            //找出同类型的节点，判断父节点是否能确定区县
                            EduAddressTreeInitial parentNode = eduAddressTreeInitialService.getById(initial.getParentId());
                            if (!ObjectUtils.isEmpty(parentNode) && (parentNode.getAreaType().equals(AreaEnum.town.getType()) ||
                                    parentNode.getAreaType().equals(AreaEnum.district.getType()) ||
                                    parentNode.getAreaType().equals(AreaEnum.village.getType()))){
                                //为路节点时，必须判断路编号是否一致 一致才能确定是同一个路
                                List<EduAddressTreeInitial> roadNumberList = eduAddressTreeInitialService.list(Wrappers.<EduAddressTreeInitial>lambdaQuery()
                                        .eq(EduAddressTreeInitial::getParentId, initial.getAddressId()));
                                for (EduAddressTreeInitial eduAddressTreeInitial : roadNumberList) {
                                    if (eduAddressTreeInitial.getAreaName().equals(parseNodes.get(i+1).getAreaName())){
                                        node.setAddressId(initial.getAddressId());
                                        node.setParentId(initial.getParentId());
                                        //改变下一个节点的id
                                        if (i <= parseNodes.size() - 1) {
                                            parseNodes.get(i+1).setParentId(initial.getAddressId());
                                        }
                                        isValid = true;
                                        //如果找到路后面的编号都是一样的，则跳出指定循环
                                        break outerRoadLoop;
                                    }
                                }
                            }
                        }
                    }else{
                        //如果不是路编号节点，则跳过当次
                        continue;
                    }
                }else{
                    //如果没有下一个节点，直接返回false 结束
                    return false;
                }
            }else {
                //如果不是路节点，则加入移除列表
                removeList.add(node);
            }
            //判断路+编号是否能确定区县
            if (isValid){
                //找到组织之后删除无效的节点
                parseNodes.removeAll(removeList);
                addressInfo.setParseNodes(parseNodes);
                return isValid;
            }

            //无法通过同名路+编号来确定，就尝试去识别小区
            if (node.getAreaType().equals(AreaEnum.detail.getType())){
                QueryWrapper<EduAddressTreeInitial> queryWrapper = new QueryWrapper<>();
                queryWrapper.lambda()
                        .select(EduAddressTreeInitial::getAddressId,
                                EduAddressTreeInitial::getAreaName,
                                EduAddressTreeInitial::getAreaType,
                                EduAddressTreeInitial::getParentId)
                        .eq(EduAddressTreeInitial::getAreaType,node.getAreaType())
                        .eq(EduAddressTreeInitial::getAreaName,node.getAreaName());
                //从解析表中查找是否有同名同类型的 小区 节点
                List<EduAddressTreeInitial> list = eduAddressTreeInitialService.list(queryWrapper);
                if (CollectionUtils.isEmpty(list)){
                    return false;
                }
                for (EduAddressTreeInitial detail : list) {
                    if (detail.getAreaName().equals(parseNodes.get(i).getAreaName())){
                        node.setAddressId(detail.getAddressId());
                        node.setParentId(detail.getParentId());
                        //改变下一个节点的id
                        if (i <= parseNodes.size() - 1) {
                            parseNodes.get(i+1).setParentId(detail.getAddressId());
                        }
                        isValid = true;
                        break;
                    }
                }
            }else{
                removeList.add(node);
            }
            //判断小区是否能确定区县
            if (isValid){
                //找到组织之后删除无效的节点
                parseNodes.removeAll(removeList);
                addressInfo.setParseNodes(parseNodes);
                return isValid;
            }
        }
        return isValid;
    }

    /**
     * 保存解析的地址信息到地址表初始表中
     * @param addressInfo 地址解析结果
     * @param eduAddress 解析完成最后一级id需要回填到 eduAddress中
     * @param initialSchoolFlag 是否初始化学区 :
     *                          是：将地址节点和学校关联数据  保存到 edu_address_tree_school
     */
    private EduAddress saveToAddressTreeInitial (AddressInfo addressInfo,EduAddress eduAddress,Boolean initialSchoolFlag) {
        if(!CollectionUtils.isEmpty(addressInfo.getParseNodes())){
            List<EduAddressTreeInitialVO> addressNodes =addressInfo.getParseNodes();
            //校验保存节点数据到eduAddressTreeInitial表/树表中
            checkAddressSaveNode(addressNodes,eduAddress);
            if (initialSchoolFlag){
                //解析好的地址节点需要和学校进行关联,从eduAddressSchool中去找关联数据
                addressSchoolService.saveTreeSchoolRelation(eduAddress,addressNodes.get(addressNodes.size() - 1));

                //如果没有抛异常
                try {
                    //锁定节点
                    List<EduAddressTree> treeLinks = addressTreeService.getLinkByTreeId(eduAddress.getAddressTreeId());
                    EduAddressTree eduAddressTree =checkAffirmFlag(treeLinks);//锁定的标志
                    //如果没有要锁定的节点，则不锁定
                    if (eduAddressTree != null) {
                        // 获取 primarySchool 字段，并判空处理
                        String primarySchool = eduAddressTree.getPrimarySchool();
                        List<String> primaryList = new ArrayList<>();
                        if (primarySchool != null && !primarySchool.isEmpty()) {
                            primaryList = Arrays.stream(primarySchool.split(",")).collect(Collectors.toList());
                        }
                        // 获取 middleSchool 字段，并判空处理
                        String middleSchool = eduAddressTree.getMiddleSchool();
                        List<String> middleList = new ArrayList<>();
                        if (middleSchool != null && !middleSchool.isEmpty()) {
                            middleList = Arrays.stream(middleSchool.split(",")).collect(Collectors.toList());
                        }
                        ArrayList<String> schoolList = new ArrayList<>();
                        schoolList.addAll(primaryList);
                        schoolList.addAll(middleList);
                        // 查询数据库中edu_address_school表中这个地址是否是原住民服务区，如果是则不锁定地址
                        QueryWrapper<EduAddressSchool> eduAddressSchoolQueryWrapper = new QueryWrapper<>();
                        eduAddressSchoolQueryWrapper.lambda()
                                .eq(EduAddressSchool::getAddressId, eduAddress.getAddressId());
                        List<EduAddressSchool> list = addressSchoolService.list(eduAddressSchoolQueryWrapper);

                        boolean canLock = true; // 默认可以锁定

                        for (EduAddressSchool eduAddressSchool : list) {
                            if ("1".equals(eduAddressSchool.getServiceAreaFlag())) {
                                canLock = false;
                                break; // 找到服务区标记后退出循环
                            }
                            if ("1".equals(eduAddressSchool.getNativeFlag())) {
                                canLock = false;
                                break; // 找到原住民标记后退出循环
                            }
                        }
                        // 如果可以锁定
                        if (canLock && !ObjectUtils.isEmpty(eduAddressTree)) {
                            // 如果父节点状态是锁定，则需要将子节点也锁定掉
                            if (eduAddressTree.getAffirmFlag().equals(1)) {
                                EduAddressTreeVO eduAddressTreeVO = Convert.convert(EduAddressTreeVO.class, eduAddressTree);
                                initialIntegration.lockDescendants(eduAddressTreeVO, schoolList, treeLinks, eduAddressTree.getPrimarySchool(), eduAddressTree.getMiddleSchool());
                            }
                        }
                    }
                }catch (Exception e){

                }


            }else{
                //将学区生成到待审核表中
            }
            //取最后地址节点id进行绑定到eduAddress中
        }
        return eduAddress;
    }


    /**
     * 是否锁定的标志
     * false:没有锁定
     * true:已经锁定，直接审核通过
     *
     * @param treeLinks
     * @return
     */
    private EduAddressTree checkAffirmFlag(List<EduAddressTree> treeLinks) {
        if (treeLinks == null) {
            return null;
        }

        for (EduAddressTree treeLink : treeLinks) {
            if (treeLink != null && treeLink.getAffirmFlag() != null && treeLink.getAffirmFlag().equals(1)) {
                return treeLink;
            }
        }
        return null;
    }


    /**
     * 取最后地址节点id进行绑定到eduAddress中
     * @param addressNode
     * @param eduAddress
     */
    private EduAddress boundNodeIdToAddress(EduAddressTreeInitial addressNode, EduAddress eduAddress) {
        //判断最后一个节点是否插入到表中
        //校验参数：是否去tree表查询数据  1去树表查询 0 去初始化表查询
        CommonVO addressParseCheck = new CommonVO();
        addressParseCheck.setParamKey("TREE_OR_INITIAL_FLAG");
        String treeOrInitialFlag = commonIntegration.getValueByKey(addressParseCheck);
        if (StringUtils.isBlank(treeOrInitialFlag)){
            treeOrInitialFlag = BoolEnum.TRUE.getType();
        }
        EduAddressTree lastNode;
        if (BoolEnum.TRUE.getType().equals(treeOrInitialFlag)){
            lastNode = addressTreeService.getById(addressNode.getAddressId());
        }else{
            EduAddressTreeInitial initial = eduAddressTreeInitialService.getById(addressNode.getAddressId());
            lastNode = Convert.convert(EduAddressTree.class, initial);
        }
        if (!ObjectUtils.isEmpty(lastNode)){
            addressNode.setAddressId(lastNode.getAddressId());
        }
        return eduAddress;
    }


    /**
     * 校验保存节点数据
     * 校验节点 是否存在数据库中，不存在进行插入
     * @param addressNodes
     */
    private void checkAddressSaveNode(List<EduAddressTreeInitialVO> addressNodes,EduAddress eduAddress) {
        //设置父级完整地址
        List<String> areaNameList =
                addressNodes.stream().map(EduAddressTreeInitialVO::getAreaName).collect(Collectors.toList());
        //排除最后一个节点
        eduAddress.setParentPath(String.join("/",areaNameList.subList(0,areaNameList.size() - 1)));
        int size = addressNodes.size();
        //校验参数：是否去tree表查询数据  1去树表查询 0 去初始化表查询
        CommonVO addressParseCheck = new CommonVO();
        addressParseCheck.setParamKey("TREE_OR_INITIAL_FLAG");
        String treeOrInitialFlag = commonIntegration.getValueByKey(addressParseCheck);
        if (StringUtils.isBlank(treeOrInitialFlag)){
            treeOrInitialFlag = BoolEnum.TRUE.getType();
        }
        for (int i = 0; i < size; i++) {
            EduAddressTreeInitialVO addressNode = addressNodes.get(i);

            if (treeOrInitialFlag.equals(BoolEnum.TRUE.getType())){
                EduAddressTree addressTreeNode = Convert.convert(EduAddressTree.class, addressNode);
                addressTreeNode.setLastNode(addressNode.getIsLastNode());
                addressTreeNode.setLeafNode(addressNode.getIsLeafNode());
                //如果数据库中不存在该节点，则进行插入
                if (BoolEnum.FALSE.getType().equalsIgnoreCase(addressNode.getExistInDB())){

                    if (originalService.getById(addressTreeNode.getAddressId())==null) {
                        addressTreeNode.setEsStatus(0);
                    } else {
                        addressTreeNode.setEsStatus(1);
                    }
                    //判断是否为最后节点，最后一个节点需要将完整地址信息进行设置
                    if (i == size - 1) {
                        addressTreeNode.setFullAddress(eduAddress.getAddressName());
                    }
                    //判断是否为叶子节点
                    addressTreeNode.setLeafNode(i == size - 1 ? 1 : 0);
                    addressTreeNode.setLastNode(i == size - 1 ? 1 : 0);
                    try {
                        addressTreeService.save(addressTreeNode);
                        if (i == size - 1) {
                            eduAddress.setAddressTreeId(addressTreeNode.getAddressId());
                        }
                    } catch (Exception e) {
                        throw new AppException("保存地址节点失败:{}"+e.getMessage());
                    }
                }else{
                    //如果存在，并且为最后一个节点，需要设置节点完整地址信息，和改变叶子节点状态
                    if (i == size - 1){
                        //如果原来节点状态不是叶子节点
                        if(addressTreeNode.getLeafNode()!=null&&addressTreeNode.getLeafNode()!=1){
                            //设置叶子节点完整地址名称
                            addressTreeNode.setFullAddress(eduAddress.getAddressName());
                            //将叶子节点状态设置为1
                            addressTreeNode.setLeafNode(1);
                            addressTreeService.saveOrUpdate(addressTreeNode);
                        }
                        eduAddress.setAddressTreeId(addressTreeNode.getAddressId());
                    }else{
                        //如果不是最后一级节点，判断原来节点是否为最后一级节点
                        if(addressTreeNode.getLastNode() == 1){
                            //进行修正 表示不是最后一级节点
                            addressTreeNode.setLastNode(0);
                            addressTreeService.saveOrUpdate(addressTreeNode);
                        }
                    }
                }
            }else{
                EduAddressTreeInitial addressTreeNode = Convert.convert(EduAddressTreeInitial.class, addressNode);
                if (BoolEnum.FALSE.getType().equalsIgnoreCase(addressNode.getExistInDB())){
                    //表示不存在 需要进行插入
                    // 判断是否已保存在参数表中
                    if (ObjectUtils.isEmpty(originalService.getById(addressNode.getAddressId()))) {
                        addressNode.setEsStatus(0);
                    } else {
                        addressNode.setEsStatus(1);
                    }
                    //判断是否为最后节点，最后一个节点需要将完整地址信息进行设置
                    if (i == size - 1) {
                        addressNode.setFullAddress(eduAddress.getAddressName());
                    }
                    addressTreeNode.setLeafNode(i == size - 1 ? 1 : 0);
                    addressTreeNode.setLastNode(i == size - 1 ? 1 : 0);
                    try {
                        eduAddressTreeInitialService.save(addressTreeNode);
                        if (i == size - 1) {
                            eduAddress.setAddressTreeId(addressTreeNode.getAddressId());
                        }
                    } catch (Exception e) {
                        throw new AppException("保存地址节点失败:{}"+e.getMessage());
                    }
                } else  {
                    //如果存在，并且为最后一个节点，需要设置节点完整地址信息，和改变叶子节点状态
                    if (i == size - 1){
                        if(addressTreeNode.getLeafNode()!=null&&addressTreeNode.getLeafNode()!=1){
                            addressTreeNode.setFullAddress(eduAddress.getAddressName());
                            addressTreeNode.setLeafNode(1);
                            eduAddressTreeInitialService.saveOrUpdate(addressTreeNode);
                        }
                        eduAddress.setAddressTreeId(addressTreeNode.getAddressId());
                    }else{
                        //如果不是最后一级节点，判断原来节点是否为最后一级节点
                        if(addressTreeNode.getLastNode() == 1){
                            //进行修正 表示不是最后一级节点
                            addressTreeNode.setLastNode(0);
                            eduAddressTreeInitialService.saveOrUpdate(addressTreeNode);
                        }
                    }
                }
            }
        }
    }

    /**
     * 将解析的地址结果转换为地址节点 addressNodes
     * @param addressInfo  解析地址结果类
     * @param addressNodes  地址节点存储器
     */
    private void setAddressData(AddressInfo addressInfo, List<EduAddressTreeInitial> addressNodes) {

        //雪花算法id生成器
        Snowflake snowflake = IdUtil.getSnowflake(workerId, (int) (Math.random() * 20 + 1));

        Integer i = 0;
        //设置 province
        if (!StringUtils.isBlank(addressInfo.getProvince())){
            EduAddressTreeInitial addressTreeInitial = new EduAddressTreeInitial();
            addressTreeInitial.setAreaName(addressInfo.getProvince());
            addressTreeInitial.setAreaCode(addressInfo.getProvinceCode());
            if (addressInfo.getProvinceId() != null){
                addressTreeInitial.setAddressId(addressInfo.getProvinceId());
            }else{
                addressTreeInitial.setAddressId(snowflake.nextId());
            }
            addressTreeInitial.setAreaType(AreaEnum.province.getType());
            addressNodes.add(addressTreeInitial);
        }
        //设置 city
        if (!StringUtils.isBlank(addressInfo.getCity())){
            EduAddressTreeInitial addressTreeInitial = new EduAddressTreeInitial();
            addressTreeInitial.setAreaName(addressInfo.getCity());
            addressTreeInitial.setAreaCode(addressInfo.getCityCode());
            if (addressInfo.getCityId() != null){
                addressTreeInitial.setAddressId(addressInfo.getCityId());
            }else{
                addressTreeInitial.setAddressId(snowflake.nextId());
            }
            addressTreeInitial.setAreaType(AreaEnum.city.getType());
            addressTreeInitial.setParentId(addressNodes.get(i).getAddressId());
            addressNodes.add(addressTreeInitial);
            i ++;
        }
        //设置 district
        if (!StringUtils.isBlank(addressInfo.getDistrict())){
            EduAddressTreeInitial addressTreeInitial = new EduAddressTreeInitial();
            addressTreeInitial.setAreaName(addressInfo.getDistrict());
            addressTreeInitial.setAreaCode(addressInfo.getDistrictCode());
            if (addressInfo.getDistrictId() != null){
                addressTreeInitial.setAddressId(addressInfo.getDistrictId());
            }else{
                addressTreeInitial.setAddressId(snowflake.nextId());
            }
            addressTreeInitial.setAddressId(addressInfo.getDistrictId());
            addressTreeInitial.setAreaType(AreaEnum.district.getType());
            addressTreeInitial.setParentId(addressNodes.get(i).getAddressId());
            addressNodes.add(addressTreeInitial);
            i ++;
        }
        //设置 town
        if (!StringUtils.isBlank(addressInfo.getTown())){
            EduAddressTreeInitial addressTreeInitial = new EduAddressTreeInitial();
            addressTreeInitial.setAreaName(addressInfo.getTown());
            addressTreeInitial.setAreaCode(addressInfo.getTownCode());
            if (addressInfo.getTownId() != null){
                long l = snowflake.nextId();
                addressTreeInitial.setAddressId(addressInfo.getTownId());
            }else{
                addressTreeInitial.setAddressId(snowflake.nextId());
            }
            addressTreeInitial.setAreaType(AreaEnum.town.getType());
            addressTreeInitial.setParentId(addressNodes.get(i).getAddressId());
            addressNodes.add(addressTreeInitial);
            i ++;
        }
        //设置village
        if (!StringUtils.isBlank(addressInfo.getVillage())){
            EduAddressTreeInitial addressTreeInitial = new EduAddressTreeInitial();
            addressTreeInitial.setAreaName(addressInfo.getVillage());
            if (addressInfo.getVillageId() != null){
                addressTreeInitial.setAddressId(addressInfo.getVillageId());
            }else{
                addressTreeInitial.setAddressId(snowflake.nextId());
            }
            if (!StringUtils.isBlank(addressInfo.getVillageCode())){
                addressTreeInitial.setAreaCode(addressInfo.getVillageCode());
            }
            addressTreeInitial.setAreaType(AreaEnum.town.getType());
            addressTreeInitial.setParentId(addressNodes.get(i).getAddressId());
            addressNodes.add(addressTreeInitial);
            i ++;
        }
        //设置 road
        if (!StringUtils.isBlank(addressInfo.getRoad())){
            EduAddressTreeInitial addressTreeInitial = new EduAddressTreeInitial();
            addressTreeInitial.setAreaName(addressInfo.getRoad());
            addressTreeInitial.setAddressId(snowflake.nextId());
            addressTreeInitial.setAreaType(AreaEnum.road.getType());
            addressTreeInitial.setParentId(addressNodes.get(i).getAddressId());
            addressNodes.add(addressTreeInitial);
            i ++;
        }
        //设置roadNumber
        if (!StringUtils.isBlank(addressInfo.getRoadNumber())){
            EduAddressTreeInitial addressTreeInitial = new EduAddressTreeInitial();
            addressTreeInitial.setAreaName(addressInfo.getRoadNumber());
            addressTreeInitial.setAddressId(snowflake.nextId());
            addressTreeInitial.setAreaType(AreaEnum.roadNumber.getType());
            addressTreeInitial.setParentId(addressNodes.get(i).getAddressId());
            addressNodes.add(addressTreeInitial);
            i ++;
        }
        //设置detail 小区/花园
        if (!StringUtils.isBlank(addressInfo.getName())){
            EduAddressTreeInitial addressTreeInitial = new EduAddressTreeInitial();
            addressTreeInitial.setAreaName(addressInfo.getName());
            addressTreeInitial.setAddressId(snowflake.nextId());
            addressTreeInitial.setAreaType(AreaEnum.detail.getType());
            addressTreeInitial.setParentId(addressNodes.get(i).getAddressId());
            addressNodes.add(addressTreeInitial);
            i ++;
        }
        //设置houseNumber 幢，楼 编号
        if (!StringUtils.isBlank(addressInfo.getHouseNumber())){
            EduAddressTreeInitial addressTreeInitial = new EduAddressTreeInitial();
            addressTreeInitial.setAreaName(addressInfo.getHouseNumber());
            addressTreeInitial.setAddressId(snowflake.nextId());
            addressTreeInitial.setAreaType(AreaEnum.houseNumber.getType());
            addressTreeInitial.setParentId(addressNodes.get(i).getAddressId());
            addressNodes.add(addressTreeInitial);
            i ++;
        }
        //设置houseNumber 单元编号
        if (!StringUtils.isBlank(addressInfo.getUnitNumber())){
            EduAddressTreeInitial addressTreeInitial = new EduAddressTreeInitial();
            addressTreeInitial.setAreaName(addressInfo.getUnitNumber());
            addressTreeInitial.setAddressId(snowflake.nextId());
            addressTreeInitial.setAreaType(AreaEnum.unitNumber.getType());
            addressTreeInitial.setParentId(addressNodes.get(i).getAddressId());
            addressNodes.add(addressTreeInitial);
            i ++;
        }
        //设置roomNumber 房间编号
        if (!StringUtils.isBlank(addressInfo.getRoomNumber())){
            EduAddressTreeInitial addressTreeInitial = new EduAddressTreeInitial();
            addressTreeInitial.setAreaName(addressInfo.getRoomNumber());
            addressTreeInitial.setAddressId(snowflake.nextId());
            addressTreeInitial.setAreaType(AreaEnum.roomNumber.getType());
            addressTreeInitial.setParentId(addressNodes.get(i).getAddressId());
            addressNodes.add(addressTreeInitial);
            i ++;
        }
        //设置其他 other
        if (!StringUtils.isBlank(addressInfo.getOtherAddress())){
            EduAddressTreeInitial addressTreeInitial = new EduAddressTreeInitial();
            addressTreeInitial.setAreaName(addressInfo.getRoomNumber());
            addressTreeInitial.setAddressId(snowflake.nextId());
            addressTreeInitial.setAreaType(AreaEnum.other.getType());
            addressTreeInitial.setParentId(addressNodes.get(i).getAddressId());
            addressNodes.add(addressTreeInitial);
            i ++;
        }
    }
}
